package org.dant.ant.extension.tasks.internal;

import java.io.*;
import java.net.*;

import org.dant.ant.extension.net.NetConstants;
import org.dant.ant.extension.net.RemoteHelper;

public class Endpoint implements Serializable {

    protected static String ip = NetConstants.DEFAULT_LOCAL_IP;
    protected static String hostname = NetConstants.DEFAULT_LOCAL_HOST;
    protected String port = Integer.toString(NetConstants.DEFAULT_RMI_PORT);
    protected String protocol = NetConstants.DEFAULT_PROTOCOL;
    protected String path = NetConstants.DEFAULT_PATH;
    protected String fullurl;
    protected String networking;
    protected File basedir;
    protected RemoteHelper rhelper;

    static {
        try {
            hostname = InetAddress.getLocalHost().getHostName();
            ip = InetAddress.getLocalHost().getHostAddress();

            if ("127.0.0.1".equals(ip) && hostname != null) {
                InetAddress[] addresses = InetAddress.getAllByName(hostname);
                for (int i = 0; i < addresses.length; i++) {
                    if (!"127.0.0.1".equals(addresses[i].getHostAddress())) {
                        ip = addresses[i].getHostAddress();
                        break;
                    }
                }
            }
        } catch (java.net.UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public Endpoint() {
    }

    public Endpoint(String h, String i, String p, String n, File d) {
        setHostname(h);
        setIp(i);
        setPort(p);
        setNetworking(n);
        setBaseDir(d);

        resolveProtocol();
    }

    public Endpoint(String fullpath) {
        parse(fullpath);
    }
  

    private void resolveProtocol() {
        try {
            System.out.println("Networking facility class: " + getNetworking());
            rhelper = (RemoteHelper) Class.forName(getNetworking()).newInstance();
        } catch (Exception cnfe) {
            //      cnfe.printStackTrace();
            rhelper = null;
            return;
        }
    
        setProtocol(rhelper.getProtocol());
        setPath(rhelper.getPath());
    }

    public void setBaseDir(File d) {
        this.basedir = d;
    }

    public File getBaseDir() {
        return this.basedir;
    }
  
    public String getNetworking() {
        return (networking != null) ? networking : "org.dant.ant.extension.net.rmi.RMIHelper";
    }

    public RemoteHelper getRemoteHelper() {
        return rhelper;
    }

    public void setNetworking(String clz) {
        this.networking = clz;
    }
  
    public String getFullURL() {
        if (fullurl != null) {
            return fullurl;
        } else if (!"127.0.0.1".equals(this.ip)) {
            return getIPEndpoint();
        }
        return getHostEndpoint();
    }

    public void setFullURL(String url) {
        this.fullurl = url;
    }

    public static String getLocalhost() {
        String host = ip;
        try {
            host = InetAddress.getLocalHost().getHostAddress();
            if (host == null || "127.0.0.1".equals(host)) {
                host = InetAddress.getLocalHost().getHostName();
            }
        } catch (java.net.UnknownHostException e) {
            e.printStackTrace();
        }
        return host;
    }
    
    public void setIp(String i) {
        this.ip = i;
    }

    public void setHostname(String h) {
        this.hostname = h;
    }

    public void setPort(String p) {
        this.port = p;
    }

    public void setProtocol(String p) {
        this.protocol = p;
    }

    public void setPath(String p) {
        this.path = p;
    }

    public String getIp() {
        return this.ip;
    }

    public String getHostname() {
        return this.hostname;
    }

    public String getPort() {
        return this.port;
    }

    public String getPath() {
        return this.path;
    }

    public String getIPEndpoint() {
        return constructEndPoint(this.ip, this.port);
    }

    public String getHostEndpoint() {
        return constructEndPoint(this.hostname, this.port);
    }

    public String constructEndPoint(String h, String p) {
        StringBuffer sb = new StringBuffer();
        sb.append(protocol);
        sb.append(h);
        sb.append(":");
        sb.append(p);
        sb.append("/");
        sb.append(path);
        return sb.toString();
    }

    public String toString() {
        return getFullURL();
    }

    private void parse(String p) {
        try {
            URL url = new URL(p);
            this.protocol = url.getProtocol();
            this.hostname = url.getHost();
            this.port = url.getPort() + "";
            this.path = url.getPath();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

